using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;
using Microsoft.StylusInput;
using Microsoft.StylusInput.PluginData;
using System.Drawing.Imaging;

namespace Woz
{
    /// <summary>
    /// the image tool class for drawing images on the canvas
    /// </summary>
    public class ImageTool : Woz.Tool
    {
        /// <summary>
        /// default constructor
        /// </summary>
        /// <param name="pCanvasControl">the canvas to draw images on</param>
        public ImageTool(Control pCanvasControl) : base(pCanvasControl)
        {
            // create image cursor
            Woz.ResourceManager.Instance.AddCursor("image", Woz.ResourceManager.Instance.Images["icon_image.png"]);

            // set up the valid modes
            this.mValidModes.Add(Woz.StaticVariables.Instance.DesignScreens);
            //this.mValidModes.Add(Woz.StaticVariables.Instance.RunScreens);
        }

        /// <summary>
        /// the name of the tool
        /// </summary>
        public override string Name
        {
            get
            { 
                return "Image";
            }
        }

        /// <summary>
        /// returns the name of the icon file
        /// </summary>
        public override string IconFileName
        {
            get
            {
                return "icon_image.png";
            }
        }

        /// <summary>
        /// get the data intersect and the in air packets
        /// </summary>
        public override DataInterestMask DataInterest
        {
            get
            {
                return base.DataInterest;
            }
        }

        protected override void OnProcessSelection()
        {
            base.SetCurrentCursor(Woz.ResourceManager.Instance.Cursors["image"]);
        }

        protected override void OnProcessDeselection()
        {
            base.SetCurrentCursor(Woz.ResourceManager.Instance.Cursors["arrow"]);
        }

        /// <summary>
        /// reset the pen tool
        /// </summary>
        public override void Reset()
        {
            // clear the temp image
            this.mCurrentImage = null;
            this.mFileName = "";

            // clear the cached images
            Woz.Image.Reset();
        }

        protected override void OnStylusDown(Point pLocation)
        {
            if (this.mCurrentImage == null)
            {
                // restrict the image to the canvas rectangle
                if (!Woz.InkSpaceConverter.Instance.InkSpaceCanvasRectangle.Contains(pLocation))
                {
                    return;
                }

                // show the open file dialog box so the user can select the image
                Woz.ResourceManager.OpenFileDialogArgs args = new Woz.ResourceManager.OpenFileDialogArgs("Select the image file", "Image files|*.bmp;*.jpg;*.jpeg;*.gif;*.png;*.tiff;*.tif;*.exif", 0);
                Woz.ResourceManager.Instance.OpenFileDialogMethod.Invoke(this, args);
                if (args.DialogResult == DialogResult.OK)
                {
                    base.InitializeGraphics();
                    this.mFileName = args.FileName;
                    this.mCurrentImage = new Woz.Image(args.FileName, pLocation);
                    this.mCurrentImage.Semitransparent = true;
                    Size imageSize = this.mCurrentImage.Size;
                    this.mCurrentImage.Move(pLocation.X - imageSize.Width / 2, pLocation.Y - imageSize.Height / 2);
                    this.mCurrentImage.Draw(base.mGraphics);
                    base.ReleaseGraphics();

                    base.SetCurrentCursor(Woz.ResourceManager.Instance.Cursors["none"]);
                }
            }

            else
            {
                // execute it and clear it
                Woz.Action action = Woz.ActionManager.Instance.CreateAction(typeof(Woz.AddImageAction), this.mFileName, this.mCurrentImage.BoundingBox.Location);
                action.Execute();

                // clear filename and current image
                this.mFileName = "";
                this.mCurrentImage = null;

                // reset the cursor
                base.SetCurrentCursor(Woz.ResourceManager.Instance.Cursors["image"]);
            }
        }

        protected override void OnInAirPackets(Point[] pLocations)
        {
            if (this.mCurrentImage != null)
            {
                // save the original bounding box
                Rectangle originalBoundingBox = this.mCurrentImage.BoundingBox;

                // move the entity over
                Size imageSize = this.mCurrentImage.Size;
                this.mCurrentImage.Move(pLocations[0].X - imageSize.Width / 2, pLocations[0].Y - imageSize.Height / 2);

                // invalidate the combined rectangles
                if (!originalBoundingBox.Equals(this.mCurrentImage.BoundingBox))
                {
                    base.InvalidateRect(Rectangle.Union(this.mCurrentImage.BoundingBox, originalBoundingBox));
                }

                // reset the cursor
                base.SetCurrentCursor(Woz.ResourceManager.Instance.Cursors["none"]);
            }

            else
            {
                // reset the cursor
                base.SetCurrentCursor(Woz.ResourceManager.Instance.Cursors["image"]);
            }
        }

        public override void Draw(Graphics pGraphics)
        {
            if (this.mCurrentImage != null)
            {
                this.mCurrentImage.Draw(pGraphics);
            }
        }

        /// <summary>
        /// the file name of the current bitmap
        /// </summary>
        private string mFileName;

        /// <summary>
        /// the current image to keep
        /// </summary>
        private Woz.Image mCurrentImage;
    }
}
